<?php
require_once 'AbstractConnection.class.php';

class Connection extends AbstractConnection {

    /**
     * Default constructor.
     */
    public function __construct($hostname, $hostport, $database, $username, $password) {
        parent::__construct($hostname, $hostport, $database, $username, $password);
        if($this->log->isTraceEnabled()) {
            $this->log->logTrace('Configurando a conexão:' .
                    "\n" . 'Hostname: ' . $hostname .
                    "\n" . 'Port: ' . $hostport .
                    "\n" . 'Database: ' . $database .
                    "\n" . 'Username: ' . $username .
                    "\n" . 'Pass: *****');
        }
    }

    /**
     * Open the connection
     */
    public function open() {
        $host = $this->dbPort != '' ? $this->dbHost . ':' . $this->dbPort : $this->dbHost;
        $this->conn = @mysqli_connect($host, $this->dbUser, $this->dbPass);
        if (!$this->conn) {
            //die('Critical Stop Error: Database Error<br />Can\'t connect to database ' . $this->dbHost . ' <br />Error: ' . mysqli_error());
            $this->log->logError('FALHA na conexão com o Servidor de Banco de Dados.');
            $result = ResultFactory::newResultFalha('Banco de Dados indisponível.',
                      'Falha na comunicação com o Banco de Dados.');
            $result->showResult();
            exit();
        } else {
            if($this->log->isDebugEnabled()) {
                $this->log->logDebug('Sucesso na conexão com o Servidor de Banco de Dados.');
            }
        }
        if (!@mysqli_select_db($this->conn, $this->dbName)) {
            //die('Critical Stop Error: Database Error<br />Can\'t use the database ' . $this->dbName . ' <br />Error: ' . mysqli_error());
            $this->log = new Log();
            $this->log->logError('FALHA na conexão com o Banco de Dados: ' . $this->dbName);
            $result = ResultFactory::newResultFalha('Erro no login',
                      'Empresa e/ou Usu&aacute;rio e/ou Senha incorreto(s).');
            $result->showResult();
            exit();
        } else {
            if($this->log->isDebugEnabled()) {
                $this->log->logDebug('Sucesso na conexão com Banco de Dados: ' . $this->dbName);
            }
        }
    }

    /**
     * Close the connection
     */
    public function close() {
        if ($this->conn) {
            $this->conn->close();
            unset($this->conn);
        }
    }

    /**
     * Use this method for Inserts, Updates and Deletes, return the num rows affected.
     * @param String $sql
     * @return number
     */
    public function executeUpdate($sql) {
        $this->executeQuery($sql);
        return $this->conn->affected_rows;
    }

    /**
     * Use this method for Selects
     * @param String $sql
     * @return resultSet
     */
    public function executeQuery($sql) {
        $result = $this->conn->query($sql);
        if (!$result) {
            $mysqlError = mysqli_error($result);
            $this->log->logError('Erro ao executar o sql:' . "\n" . $sql);
            $this->log->logError('Erro MySQL:' . "\n" . $mysqlError);
        }
        return $result;
    }
    
    public function getMysqli() {
        return $this->conn;
    }

    /**
     * Retorna uma matriz associativa que corresponde a linha obtida e move o ponteiro interno dos dados adiante.
     * Utilizado para executar o loop while e ler todas as linhas do resultado.
     * @param returned by executeQuery $result
     * @return mysqli_fetch_assoc
     */
    public function fetchAssoc($result) {
        return $result->fetch_assoc();
    }

    /**
     * Get num rows returned by select or show command.
     * @param returned by executeQuery $result
     * @return mysqli_num_rows
     */
    public function getNumRows($result) {
        return $result->num_rows;
    }

    /**
     * Get AutoIncrement Id
     * @return mysqli_insert_id
     */
    public function getAutoId() {
        return $this->conn->insert_id;
    }

    /**
     * Free the result from the memory.
     * @return mysqli_free_result
     */
    public function freeResult($result) {
        $result->free();
    }
    
    /**
     * Transaction Rollback.
     */
    public function rollback() {
        $this->conn->rollback();
    }

}
